#include "RapidFireButton.h"



// constructor based on a GenericButton (period defaults to 0.05)
RapidFireButton::RapidFireButton(GenericButton *button, float period)
{
	m_button = button;
	Init(period);
}

// initialize member variables, start Notifier
void RapidFireButton::Init(float period)
{
	m_controlLoop = new Notifier(RapidFireButton::CallUpdate, this);
	
	m_enabled = false;
	
	m_pressed = false;
	m_output = false;
	
	m_on_samples = 1;
	m_off_samples = 1;
	
	m_controlLoop->StartPeriodic(period);
}

// set the time (in seconds) between samples
void RapidFireButton::SetSampleRate(float period)
{
	m_controlLoop->Stop();
	m_controlLoop->StartPeriodic(period);
}


// for how many samples should the output be on (while the button is pressed)
void RapidFireButton::SetOnSamples(int number_of_samples)
{
	m_on_samples = number_of_samples;
}

// for how many samples should the output be off (while the button is pressed)
void RapidFireButton::SetOffSamples(int number_of_samples)
{
	m_off_samples = number_of_samples;
}



/*
 * Call the Update method as a non-static method.
 * Do fancy stuff to setup the "this" pointer
 */
void RapidFireButton::CallUpdate(void *ob)
{
	RapidFireButton *button_ob = (RapidFireButton*) ob;
	button_ob->Update();
}


// is the button on? - uses rapid fire mode
bool RapidFireButton::Get()
{
	//return m_pressed;
	return m_output;
}

// this function is called periodically to monitor the status of the button and act accordingly
void RapidFireButton::Update()
{
	//printf("update called\n");
	if (m_enabled)
	{
		// is button pressed?
		if (m_button->Get())
		{
			m_count++;
			
			// if the button was just pressed, set output to on (so that the switch begins on when the button is pressed)
			if (m_pressed == false)
			{
				m_output = true;
			}
			
			m_pressed = true;
			
			// if the output is currently off and m_on_samples have elapsed, turn the output on
			//if (m_pressed == false && m_count >= m_off_samples)
			if (m_output == false && m_count >= m_off_samples)
			{
				//m_pressed = true;
				m_output = true;
				m_count = 0; // reset count
			}
			
			// if the output is currently on and m_off_samples have elapsed, turn the output off
			//else if (m_pressed == true && m_count >= m_on_samples)
			else if (m_output == true && m_count >= m_on_samples)
			{
				//m_pressed = false;
				m_output = false;
				m_count = 0; // reset count
			}
		}
		else // button is not pressed: output is off, reset count
		{
			m_count = 0;
			m_pressed = false;
			m_output = false;
		}
		
	}	
}

// enable the button (it now responds to button pushes)
void RapidFireButton::Enable()
{
	m_enabled = true;
}

// disable the button (it now ignores button pushes)
void RapidFireButton::Disable()
{
	m_enabled = false;
}


